/*
 *
 * @Author     : Yongsheng.X
 * @Date       : 2019-09-26 17:04
 * @Description: 摄像头扫码功能
 *
 */

import 'dart:async';
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:permission_handler/permission_handler.dart';

import 'package:platform_service/src/scanner/qr_code_dart_scan/lib/qr_code_dart_scan.dart';
import 'scanner_method_channel.dart';

/// 自定义H5扫码页  应用入口 _materialApp 中进行赋值
/// 小程序H5  customH5ScannerPage = JsUtil.startWxScanQRCode()
/// 飞书H5  customH5ScannerPage = JsUtil.startFSScanQRCode()
Future<String?> Function()? h5NDScannerPage;

/// 是否是pda模式   true:显示红外扫描img  不启用摄像头
bool isPDAScanModel = false;
ImageProvider? imagePdaScan;

class NDScannerController {
  final NDMethodChannelScanner? _platformController;

  NDScannerController._(this._platformController);

  Future<void>? start() {
    return _platformController?.start();
  }

  Future<void>? dispose() {
    return _platformController?.dispose();
  }

  Future<void>? resume() {
    return _platformController?.resume();
  }

  Future<void>? pause() {
    return _platformController?.pause();
  }

  Future<void>? stop() {
    return _platformController?.stop();
  }
}

typedef void NDScannerCreatedCallback(NDScannerController controller);

class NDPlatformCallBackHandler implements NDScannerPlatformCallbacksHandler {
  NDScannerWidget _widget;

  NDPlatformCallBackHandler(this._widget);

  @override
  void onScanResult(String? result) {
    _widget.onResult?.call(result);
  }

  @override
  Future<void> Function() controllerDispose = () {
    return Future.value();
  };

  @override
  Future Function() pause = () {
    return Future.value();
  };

  @override
  Future Function() resume = () {
    return Future.value();
  };

  @override
  Future Function() start = () {
    return Future.value();
  };

  @override
  Future Function() stop = () {
    return Future.value();
  };
}

class NDScannerWidget extends StatefulWidget {
  final void Function(String? result)? onResult;
  final NDScannerCreatedCallback? onScannerCreate;
  final double? width;
  final double? height;

  //PlatformView的高度和宽度是屏幕高度
  final bool shouldBound;
  final bool continueScan;

  /// widget dispose 时是否 disposeScanner   默认true
  final bool disposeScanner;

  /// Android 系统版本
  final int? androidSdkInt;

  NDScannerWidget({
    this.onResult,
    this.onScannerCreate,
    this.width,
    this.height,
    this.shouldBound = false,
    this.continueScan = false,
    this.disposeScanner = true,
    this.androidSdkInt,
  });

  @override
  _NDScannerWidgetState createState() => _NDScannerWidgetState();
}

class _NDScannerWidgetState extends State<NDScannerWidget> {
  String _viewType = "com.newcore.demo.flutter.plugin/scanner";

  late NDPlatformCallBackHandler _platformCallBackHandler;

  final Completer<NDScannerController> _controller =
      Completer<NDScannerController>();

  ///设备权限是否已授权
  var _haveAuthorityGranted = false;

  Future _checkCameraStatus() async {
    var cameraStatus = await Permission.camera.status;
    var cameraGranted = false;

    if (cameraStatus.isDenied || cameraStatus.isPermanentlyDenied) {
      cameraStatus = await Permission.camera.request();
      if (!cameraStatus.isGranted && context.mounted) {
        showDialog(
            context: context,
            builder: (ctx) {
              return AlertDialog(
                title: const Text('警告'),
                content: const Text('请授予App相机使用权限，否则扫码功能将不可用\r授权后请重新进入扫码页'),
                actions: [
                  TextButton(
                    onPressed: () async {
                      Navigator.of(ctx).pop();
                    },
                    child: const Text('确定'),
                  )
                ],
              );
            });
      }
    }
    if (cameraStatus.isGranted) {
      cameraGranted = true;
    }

    if (cameraGranted) {
      setState(() {
        _haveAuthorityGranted = true;
      });
    }
  }

  @override
  void initState() {
    _platformCallBackHandler = NDPlatformCallBackHandler(widget);
    if (!kIsWeb && !isPDAScanModel) {
      //判断相机权限
      _checkCameraStatus();
    }
    super.initState();
  }

  @override
  void didUpdateWidget(NDScannerWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    _controller.future.then((controller) {
      _platformCallBackHandler._widget = widget;
    });
  }

  void _onScannerViewPlatformCreated(int id) {
    debugPrint("[Scanner] OnScannerViewPlateformCreated");
    NDMethodChannelScanner? platformController;
    if (!kIsWeb) {
      platformController = NDMethodChannelScanner(id, _platformCallBackHandler);
    }
    NDScannerController controller = NDScannerController._(platformController);
    _controller.complete(controller);
    if (widget.onScannerCreate != null) {
      widget.onScannerCreate!(controller);
    }
  }

  @override
  Widget build(BuildContext context) {
    debugPrint("on ScannerWidget Build");
    if (kIsWeb) {
      return h5NDScannerPage == null
          ? QRCodeDartScanView(
              platformCallBackHandler: _platformCallBackHandler,
              scanInvertedQRCode: true,
              widthPreview: widget.width ?? double.maxFinite,
              heightPreview: widget.height ?? double.maxFinite,
              typeCamera: TypeCamera.front,
              // 需要设置成front 手机端才是后置摄像头 typeScan：H5不支持live
              typeScan: TypeScan.live,
              onCapture: (Result result) {
                if (widget.onResult != null) {
                  widget.onResult!(result.text);
                }
              },
            )
          : Container(
              height: double.maxFinite,
              width: double.maxFinite,
              padding: const EdgeInsets.only(top: 150),
              child: Column(
                children: [
                  ElevatedButton(
                    style: ButtonStyle(
                      padding: MaterialStateProperty.all<EdgeInsets>(
                          const EdgeInsets.symmetric(horizontal: 16)),
                      minimumSize:
                          MaterialStateProperty.all<Size?>(const Size(44, 44)),
                      maximumSize: MaterialStateProperty.all<Size?>(
                          const Size.fromHeight(44)),
                    ),
                    onPressed: () async {
                      var result = await h5NDScannerPage!();
                      if (widget.onResult != null) {
                        widget.onResult!(result);
                      }
                    },
                    child: const Text('点击扫码'),
                  ),
                  const Spacer(),
                ],
              ),
            );
    }
    if (isPDAScanModel) {
      var screenHeight = MediaQuery.of(context).size.height;
      var previewHeight = widget.height ?? screenHeight;
      var rate = previewHeight / 812;
      return PDAModelTipsWidget(heightRate: rate);
    }
    return _haveAuthorityGranted
        ? Platform.isIOS
            ? UiKitView(
                viewType: _viewType,
                onPlatformViewCreated: (id) {
                  _onScannerViewPlatformCreated(id);
                },
                creationParams: <String, dynamic>{
                  "width": widget.width ?? MediaQuery.of(context).size.width,
                  "height": widget.height ?? MediaQuery.of(context).size.height,
                  "bound": widget.shouldBound,
                  "continueScan": widget.continueScan,
                },
                creationParamsCodec: const StandardMessageCodec(),
              )
            : PlatformViewLink(
                viewType: _viewType,
                surfaceFactory:
                    (BuildContext context, PlatformViewController controller) {
                  return AndroidViewSurface(
                    controller: controller as AndroidViewController,
                    hitTestBehavior: PlatformViewHitTestBehavior.opaque,
                    gestureRecognizers: const <Factory<
                        OneSequenceGestureRecognizer>>{},
                  );
                },
                onCreatePlatformView: (PlatformViewCreationParams params) {
                  final AndroidViewController controller =
                      widget.androidSdkInt == null ||
                              widget.androidSdkInt! >= 23
                          ? PlatformViewsService.initAndroidView(
                              id: params.id,
                              viewType: _viewType,
                              layoutDirection: TextDirection.ltr,
                              creationParams: <String, dynamic>{
                                "width": widget.width ??
                                    MediaQuery.of(context).size.width,
                                "height": widget.height ??
                                    MediaQuery.of(context).size.height,
                                "bound": widget.shouldBound,
                                "continueScan": widget.continueScan
                              },
                              creationParamsCodec: const StandardMessageCodec(),
                            )
                          : PlatformViewsService.initExpensiveAndroidView(
                              id: params.id,
                              viewType: _viewType,
                              layoutDirection: TextDirection.ltr,
                              creationParams: <String, dynamic>{
                                "width": widget.width ??
                                    MediaQuery.of(context).size.width,
                                "height": widget.height ??
                                    MediaQuery.of(context).size.height,
                                "bound": widget.shouldBound,
                                "continueScan": widget.continueScan
                              },
                              creationParamsCodec: const StandardMessageCodec(),
                            );
                  controller.addOnPlatformViewCreatedListener(
                    params.onPlatformViewCreated,
                  );
                  controller.addOnPlatformViewCreatedListener(
                    _onScannerViewPlatformCreated,
                  );
                  controller.create();
                  return controller;
                },
              )
        : const Center(
            child: Text(
              '您没有授权设备权限，无法使用该功能',
              style: TextStyle(color: Color(0xFF666666), fontSize: 12),
            ),
          );
  }

  @override
  void dispose() {
    //Android 自动dispose

    if (!kIsWeb) {
      if (Platform.isIOS) {
        if (widget.disposeScanner) {
          _controller.future.then((value) => value.dispose());
        }
      }
    }

    super.dispose();
  }
}

/// PDA 模式提示信息 widget
class PDAModelTipsWidget extends StatelessWidget {
  const PDAModelTipsWidget({super.key, this.heightRate = 1});

  /// 高度比率，默认1
  final double heightRate;

  @override
  Widget build(BuildContext context) {
    var heightRate = this.heightRate;
    if (heightRate == 1) {
      var screenHeight = MediaQuery.of(context).size.height;
      heightRate = screenHeight / 812;
    }
    return Container(
      height: double.maxFinite,
      width: double.maxFinite,
      padding: EdgeInsets.only(top: 75 * heightRate),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          if (imagePdaScan != null)
            Image(
              image: imagePdaScan!,
              width: 174 * heightRate,
              height: 309 * heightRate,
            ),
          Padding(
            padding: EdgeInsets.only(top: 32 * heightRate),
            child: Text(
              '请使用设备的红外扫描功能',
              style: TextStyle(
                  color: Colors.black.withOpacity(0.65),
                  fontSize: 18,
                  fontWeight: FontWeight.w500),
            ),
          ),
          Padding(
            padding: EdgeInsets.only(top: 8 * heightRate),
            child: Text(
              '如需切换扫描方式请前往"我的-设置-扫码设置"修改',
              style: TextStyle(
                color: Colors.black.withOpacity(0.45),
                fontSize: 14,
              ),
            ),
          ),
          const Spacer(),
        ],
      ),
    );
  }
}
